package jannex.sql.extensions;

import jannex.Jannex;
import jannex.internal.ReflectionUtils;
import jannex.sql.JxDatabaseMetaData;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

public class DatabaseMetaDataProxy implements InvocationHandler {

    private final Map<String, Object> cache = new HashMap<>();

    private DatabaseMetaDataProxy(JxDatabaseMetaData databaseMetaData) {
        for (Method method : databaseMetaData.getClass().getMethods()) {
            if (method.getParameterTypes().length == 0 &&
                    method.getReturnType() == String.class ||
                    method.getReturnType().isPrimitive()) {
                try {
                    cache.put(method.getName(), method.invoke(databaseMetaData));
                } catch (IllegalAccessException | InvocationTargetException ignored) {
                }
            }
        }
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (cache.containsKey(method.getName())) {
            return cache.get(method.getName());
        }
        return ReflectionUtils.getDefault(method.getReturnType());
    }

    public static JxDatabaseMetaData newInstance(JxDatabaseMetaData databaseMetaData) {
        return (JxDatabaseMetaData) Proxy.newProxyInstance(Jannex.class.getClassLoader(), new Class<?>[]{JxDatabaseMetaData.class}, new DatabaseMetaDataProxy(databaseMetaData));
    }

}
